//
//  MKUITabBarItemViewContainerCollectionView.m
//  MKUI
//
//  Created by sushangjin on 16/3/29.
//  Copyright © 2016年 sushangjin. All rights reserved.
//

#import "MKUITabBarItemViewContainerCollectionView.h"
#import "MKUITabBarItemCollectionViewCell.h"
#import "UIView+MKUI.h"
#import "MKUITabBarController.h"
#import "MKUITabBarItemIndicatorView.h"
#import "MKUITabBarItemSeparatorView.h"
#import "UIColor+MKUI.h"
#import "UICollectionViewFlowLayout+MKUI.h"
@interface __MKUITabBarItemViewContainerUICollectionView: MKUICollectionFlowLayoutView

@end
@implementation __MKUITabBarItemViewContainerUICollectionView
//在ios10下，contentInset会被错误的设置，这里进行专门适配,只接收UIEdgeInsetsZero
- (void)setContentInset:(UIEdgeInsets)contentInset{
    if(UIEdgeInsetsEqualToEdgeInsets(contentInset, UIEdgeInsetsZero)){
        [super setContentInset:contentInset];
    }else{
        
    }
}
@end

@interface MKUITabBarItemViewContainerCollectionView ()
@property(nonatomic,strong) UIView *itemIndicatorView;
@property(nonatomic,strong) NSMutableArray<UIView *> *separatorViews;
@property(nonatomic,strong) NSMutableArray<UIView *> *separatorViewCaches;
@property(nonatomic,strong) NSValue *cacheFitedSize;
@end

@implementation MKUITabBarItemViewContainerCollectionView
- (id)initWithFrame:(CGRect)frame{
	if (self=[super initWithFrame:frame]) {
        self.fillBounds = YES;
        self.itemCollectionCellClass = [MKUITabBarItemCollectionViewCell class];
        
		//
		self.collectionView = [[__MKUITabBarItemViewContainerUICollectionView alloc] initWithFrame:self.bounds];
        self.collectionView.scrollsToTop = NO;
		self.collectionView.alwaysBounceHorizontal = NO;
        self.collectionView.showsHorizontalScrollIndicator = NO;
        self.collectionView.showsVerticalScrollIndicator = NO;
        
        self.collectionView.collectionViewFlowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        self.collectionView.collectionViewFlowLayout.minimumInteritemSpacing = 0;
        self.collectionView.collectionViewFlowLayout.minimumLineSpacing = 0;
        self.collectionView.collectionViewFlowLayout.sectionInset = UIEdgeInsetsZero;
		[self addSubview:self.collectionView];
		//
		self.collectionView.model.forwardDelegate = self;
        
        self.separatorViewCaches = [[NSMutableArray alloc] init];
        self.collectionView.backgroundColor = [UIColor mk_colorWithLight:[UIColor whiteColor] dark:[UIColor blackColor]];
	}
	return self;
}
- (void)layoutSubviews{
	[super layoutSubviews];
	CGRect bounds = self.bounds;
	CGRect f1 = bounds;
	BOOL collectionFrameChange = !CGRectEqualToRect(f1, self.collectionView.frame);
	self.collectionView.frame = f1;
	if(collectionFrameChange){
		[self.collectionView.model reloadCollectionViewData];
        [self scrollToSelectedIndexWithAnimated:NO];
        [self __refreshCurrentIndicatorWithAnimated:NO];
        [self reloadSeparator];
	}
}
- (CGSize)sizeThatFits:(CGSize)size{
    CGSize s = [self __sizeThatFits:size];
    if(self.fillBounds){
        s.width = size.width;
    }
    return s;
}
- (CGSize)__sizeThatFits:(CGSize)size{
	CGSize sizeFits = size;
    if(self.cacheFitedSize){
        sizeFits = [self.cacheFitedSize CGSizeValue];
    }else{
        sizeFits.width = 0;
        sizeFits.height = 0;
        if([self.collectionView.model numberOfCells]>0){
            CGRect originBounds = self.collectionView.bounds;
            CGRect bounds = originBounds;
            bounds.size = size;
            self.collectionView.bounds = bounds;
            CGFloat h = 0;
            for (MKUICollectionViewCellModel *cm in [self.collectionView.model allCellModels]) {
                Class cellClass = cm.cellClass;
                if([cellClass respondsToSelector:@selector(sizeWithCollectionView:collectionCellModel:)]){
                    CGSize s1 = [cellClass sizeWithCollectionView:self.collectionView collectionCellModel:cm];
                    sizeFits.width += s1.width;
                    h = MAX(h,s1.height);
                }
            }
            sizeFits.width += (self.collectionView.model.numberOfCells-1)*self.collectionView.collectionViewFlowLayout.minimumInteritemSpacing;
            UIEdgeInsets sectionInsets = self.collectionView.collectionViewFlowLayout.sectionInset;
            sizeFits.width += sectionInsets.left+sectionInsets.right;
            sizeFits.height = sectionInsets.top+sectionInsets.bottom+h;
            self.collectionView.bounds = originBounds;
            sizeFits.width = MIN(size.width,sizeFits.width);
        }
        self.cacheFitedSize = [NSValue valueWithCGSize:sizeFits];
    }
	return sizeFits;
}

#pragma mark - itemIndicator 指示器
- (BOOL)showScrollProgress{
    return self.itemIndicatorViewClass != nil;
}
- (void)setItemIndicatorViewClass:(Class)itemIndicatorViewClass{
    if(_itemIndicatorViewClass!=itemIndicatorViewClass){
        if(self.itemIndicatorView){
            [self.itemIndicatorView removeFromSuperview];
        }
        _itemIndicatorViewClass = itemIndicatorViewClass;
        if(_itemIndicatorViewClass){
            self.itemIndicatorView = [[_itemIndicatorViewClass alloc] init];
            [self.collectionView addSubview:self.itemIndicatorView];
        }
    }
}
- (void)__refreshCurrentIndicatorWithAnimated:(BOOL)animated{
    if([self showScrollProgress]){
        if(animated){
            CGRect f = [self itemIndicatorRectWithScrollFromIndex:self.selectedIndex to:self.selectedIndex withProgress:0];//计算itemIndicatorRectWithScrollFromIndex时，有可能会设置collectionview的offset，因此不能放到动画block中去
            [UIView animateWithDuration:0.25 animations:^{
                self.itemIndicatorView.mk_frameSafety = f;
            }];
        }else{
            self.itemIndicatorView.mk_frameSafety = [self itemIndicatorRectWithScrollFromIndex:self.selectedIndex to:self.selectedIndex withProgress:0];
        }
    }
}
- (__kindof UICollectionViewCell *)itemCollectionViewCellForIndex:(NSInteger)index{
    if(!(index>=0&&index<self.collectionView.model.numberOfCells)){
        return nil;
    }
    NSIndexPath *p = [NSIndexPath indexPathForItem:index inSection:0];
    UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:p];
    if(!cell){
        //cell还未显示出来
        CGPoint offset = self.collectionView.contentOffset;
        [self.collectionView scrollToItemAtIndexPath:p atScrollPosition:(UICollectionViewScrollPositionCenteredHorizontally) animated:NO];
        [self.collectionView layoutIfNeeded];
        cell = [self.collectionView cellForItemAtIndexPath:p];
        self.collectionView.contentOffset = offset;
    }
    return cell;
}
- (CGRect)itemIndicatorRectWithScrollFromIndex:(NSInteger)fromIndex to:(NSInteger)toIndex withProgress:(CGFloat)progress{
    CGRect bounds = self.collectionView.bounds;
    CGRect f2 = bounds;
    f2.size.height = bounds.size.height;
    f2.origin.y = CGRectGetMaxY(bounds)-f2.size.height;
    
    CGRect r1 = [self itemContentRectForIndex:fromIndex];
    CGRect r2 = [self itemContentRectForIndex:toIndex];
    f2.size.width = r1.size.width+(r2.size.width-r1.size.width)*progress;
    f2.origin.x = CGRectGetMidX(r1)-(f2.size.width)*0.5+(CGRectGetMidX(r2)-CGRectGetMidX(r1))*progress;
    return f2;
}
- (CGRect)itemContentRectForIndex:(NSInteger)index{
    UICollectionViewCell *cell = [self itemCollectionViewCellForIndex:index];
    CGRect r;
    CGRect itemIndicatorRect = CGRectZero;
    if([cell isKindOfClass:[MKUITabBarItemCollectionViewCell class]]){
        MKUITabBarItemCollectionViewCell *c = (MKUITabBarItemCollectionViewCell *)cell;
        itemIndicatorRect = c.itemIndicatorRect;
    }
    if(!CGRectEqualToRect(itemIndicatorRect, CGRectZero)){
        r = [self.collectionView convertRect:itemIndicatorRect fromView:cell];
    }else{
        r = [self.collectionView convertRect:cell.frame fromView:cell.superview];
    }
    return r;
}
#pragma mark - separator 分隔线
- (void)setSeparatorViewClass:(Class)separatorViewClass{
    if(_separatorViewClass!=separatorViewClass){
        //切换显示效果时，移除旧的分隔线
        if(_separatorViewClass){
            for (UIView *v in [self.collectionView mk_subviewsWithClass:_separatorViewClass]) {
                [v removeFromSuperview];
            }
            self.separatorViews = nil;
        }
        _separatorViewClass = separatorViewClass;
    }
}
- (UIView *)getSeparatorView{
    if(![self showSeparator]){
        return nil;
    }
    Class c = [self separatorViewClass];
    UIView *v = nil;
    while (self.separatorViewCaches.count>0) {
        v = [self.separatorViewCaches lastObject];
        [self.separatorViewCaches removeLastObject];
        if([v isKindOfClass:c]){
            break;
        }else{
            v = nil;
        }
    }
    if(!v){
        v = [[c alloc] init];
    }
    return v;
}
- (BOOL)showSeparator{
    return self.separatorViewClass != nil;
}
- (NSArray<NSValue *> *)needSeparatorOfCellFrame{
    NSMutableArray *rectList = [[NSMutableArray alloc] init];
    NSArray<UICollectionViewCell *> *cells = [self.collectionView mk_subviewsWithClass:[self itemCollectionCellClass]];
    for (UICollectionViewCell *cell in cells) {
        if(!cell.hidden){
            [rectList addObject:@(cell.frame)];
        }
    }
    [rectList sortUsingComparator:^NSComparisonResult(NSValue *obj1, NSValue *obj2) {
        CGRect r1 = [obj1 CGRectValue];
        CGRect r2 = [obj2 CGRectValue];
        return [@(r1.origin.x) compare:@(r2.origin.x)];
    }];
    return rectList;
}
- (void)reloadSeparator{
    if(![self showSeparator]){
        for (UIView *v in self.separatorViews) {
            [v removeFromSuperview];
        }
        self.separatorViews = nil;
        [self.separatorViewCaches removeAllObjects];
        return;
    }
    [self.collectionView layoutIfNeeded];
    NSArray<NSValue *> *cellFrames = [self needSeparatorOfCellFrame];
    NSInteger separatorCount = MAX(0,(NSInteger)cellFrames.count-1);
    NSArray<UIView *> *oldSeparators = [self.collectionView mk_subviewsWithClass:[self separatorViewClass]];
    
    NSMutableArray<UIView *> *separators = [[NSMutableArray alloc] init];
    for (int i=0;i<separatorCount;i++) {
        UIView *v = nil;
        if(i<oldSeparators.count){
            v = oldSeparators[i];
        }else{
            v = [self getSeparatorView];
            [self.collectionView addSubview:v];
        }
        [separators addObject:v];
    }
    for (NSInteger i=separatorCount; i<oldSeparators.count; i++) {
        UIView *v = oldSeparators[i];
        [v removeFromSuperview];
        [self.separatorViewCaches addObject:v];
    }
    self.separatorViews = separators;
    
    CGRect bounds = self.collectionView.bounds;
    bounds.origin = CGPointZero;
    for (int i=0;i<separators.count;i++) {
        UIView *v = separators[i];
        CGRect r1 = [cellFrames[i] CGRectValue];
        CGRect r2 = [cellFrames[i+1] CGRectValue];
        CGFloat x1 = CGRectGetMaxX(r1);
        CGFloat x2 = CGRectGetMinX(r2);
        CGFloat center = x1+(x2-x1)*0.5;
        
        CGRect f = CGRectZero;
        CGSize s = [v sizeThatFits:bounds.size];
        f.size.height = bounds.size.height;
        f.size.width = s.width;
        f.origin.x = center-f.size.width*0.5;
        v.frame = f;
    }
}

- (void)__reloadModelData{
    self.cacheFitedSize = nil;
	[self.collectionView.model removeAllSectionModels];
	@MK_WEAKIFY(self);
	Class tabBarItemCollectionCellClass = self.itemCollectionCellClass;
	for (UITabBarItem *item in self.items) {
        MKUICollectionViewCellModel *cm = [MKUICollectionViewCellModel modelWithValue:item cellClass:[MKUITabBarItemCollectionViewCell class]];
		if(tabBarItemCollectionCellClass){
			cm.cellClass = tabBarItemCollectionCellClass;
		}
		cm.selected = item==self.selectedItem;
		cm.whenClick = ^(MKUICollectionViewCellModel *cm){
			@MK_NORMALIZEANDNOTNIL(self);
            NSInteger index = cm.indexInSectionModel;
            if(![self.tabBarController shouldSelectIndex:index]){
                return;
            }
			[self.collectionView.model selectCellModel:cm];
            
            self.selectedIndex = index;
            [self.tabBarController itemContainerDidSelectIndex:index animated:YES];
            [self.collectionView.model reloadCollectionViewData];
            dispatch_async(dispatch_get_main_queue(), ^{
                [self scrollToSelectedIndexWithAnimated:YES];
            });
		};
		[self.collectionView.model addCellModel:cm];
	}
	[self.collectionView.model reloadCollectionViewData];
    [self.collectionView layoutIfNeeded];
}
- (void)reloadDataWithAnimated:(BOOL)animated{
    [self __reloadModelData];
    [self scrollToSelectedIndexWithAnimated:animated];
    [self reloadSeparator];
}
- (void)didScrollFromIndex:(NSInteger)fromIndex to:(NSInteger)toIndex withProgress:(CGFloat)progress{
    if([self showScrollProgress]){
        self.itemIndicatorView.mk_frameSafety = [self itemIndicatorRectWithScrollFromIndex:fromIndex to:toIndex withProgress:progress];
    }
}
- (void)scrollToSelectedIndexWithAnimated:(BOOL)animated{
    NSInteger index = self.selectedIndex;
    if(!(index>=0&&index<self.collectionView.model.numberOfCells)){
        [self __refreshCurrentIndicatorWithAnimated:animated];
        return;
    }
    [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0] atScrollPosition:(UICollectionViewScrollPositionCenteredHorizontally) animated:animated];
    if([self contentContainerCanScrollContent]){
        //由于scroll在滚动时，都会通知标签容器，更新指示器位置，所以reload时不刷新
    }else{
        [self __refreshCurrentIndicatorWithAnimated:animated];
    }
}
#pragma mark - delegate:UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
	CGRect bounds = collectionView.bounds;
	CGSize size = CGSizeZero;
    
    NSInteger cellCount = self.collectionView.model.numberOfCells;
    if(cellCount<=1){
        size.width = bounds.size.width;
    }else if(cellCount==2){
        size.width = bounds.size.width*0.5;
    }else{
        CGSize sizeFits = [self __sizeThatFits:bounds.size];
        MKUICollectionViewCellModel *cm = (MKUICollectionViewCellModel *)[self.collectionView.model cellModelAtIndexPath:indexPath];
        Class cellClass = cm.cellClass;
        if([cellClass respondsToSelector:@selector(sizeWithCollectionView:collectionCellModel:)]){
            size = [cellClass sizeWithCollectionView:self.collectionView collectionCellModel:cm];
        }
        if(sizeFits.width<=bounds.size.width&&cellCount>0){//内容不超过外层视图,此时调整每个单元格大小，使它们之间的间隔相同
             size.width += (bounds.size.width-sizeFits.width)/cellCount;
        }
        size.width = MIN(size.width,bounds.size.width*0.75);//控制长度不能超过75%
    }
    
    size.height = bounds.size.height;
	return size;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    [self reloadSeparator];
}
- (void)dealloc{
    //ios10时，会因为实现了scrollViewDidScroll：方法，导致闪退，需要手动清空delegate
    self.collectionView.delegate = nil;
}

- (void)doesNotRecognizeSelector:(SEL)aSelector{
    if(self.collectionView.dataSource==nil){
        //ios内存释放机制，导致dataSource已经空了，但delegate还保持为自己。此时不应该响应任何方法了
        return;
    }
    [super doesNotRecognizeSelector:aSelector];
}
@end

@implementation MKUITabBarController (MKUITabBarItemViewContainerCollectionView)
- (MKUITabBarItemViewContainerCollectionView *)itemCollectionContainer{
    if([self.itemContainer isKindOfClass:[MKUITabBarItemViewContainerCollectionView class]]){
        return self.itemContainer;
    }
    return nil;
}
@end
